#include "sys_common.h"

#if defined(MIX_OS)
#include "os/os_thread.h"
#include "os/os_mutex.h"
#elif defined(MIX_RTK) /* #if defined(MIX_OS) */
#include "rtk_thread.h"
#include "rtk_mutex.h"
#include "rtk_service.h"
#elif defined(MIX_K_KIT) /* #elif defined(MIX_RTK) */
#include "k_kit.h"
#else /* #elif defined(MIX_K_KIT)  */
#include "drivers/chip/clk.h"
#endif /* #if defined(MIX_OS) */

/**
 * @brief 锁定
 *
 * @param lock_hdl 对象
 * @param wait_ms 超时时间（毫秒）， SYS_LOG_FOREVER 表示一直等待
 * @return int 0 表示操作成功；
 * @return int 1 表示超时；
 * @return int -1 表示对象无效或操作失败
 */
int sys_lock(const sys_lock_t *lock_hdl, size_t wait_ms)
{
    if (lock_hdl)
    {
#if defined(MIX_OS)

        if (lock_hdl->hdl == NULL)
        {
            if (os_mutex_create((os_mutex_t *)lock_hdl) != OS_OK)
            {
                return -1;
            }
        }

        if (os_mutex_lock((os_mutex_t *)lock_hdl, wait_ms) == OS_OK)
        {
            return 0;
        }
        else
        {
            return 1;
        }

#elif defined(MIX_RTK) /* #if defined(MIX_OS) */

        if (lock_hdl->hdl == NULL)
        {
            if (rtk_mutex_create((rtk_mutex_t *)lock_hdl, NULL) != RTK_OK)
            {
                return -1;
            }
        }

        if (rtk_mutex_lock((rtk_mutex_t *)lock_hdl, rtk_msec_to_ticks(wait_ms)) == RTK_OK)
        {
            return 0;
        }
        else
        {
            return 1;
        }

#else /* #elif defined(MIX_RTK) */

        return 0;

#endif /* #if defined(MIX_OS) */
    }

    return -1;
}

/**
 * @brief 解锁
 *
 * @param lock_hdl 对象
 */
void sys_unlock(const sys_lock_t *lock_hdl)
{
    if (lock_hdl)
    {
#if defined(MIX_OS)

        os_mutex_unlock((os_mutex_t *)lock_hdl);

#elif defined(MIX_RTK) /* #if defined(MIX_OS) */

        rtk_mutex_unlock((rtk_mutex_t *)lock_hdl);

#endif /* #if defined(MIX_OS) */
    }
}

/**
 * @brief 延时。注意只允许线程使用
 * 
 * @param delay_ms 毫秒
 */
void sys_delay(size_t delay_ms)
{
#if defined(MIX_OS)

    os_thread_sleep(delay_ms);

#elif defined(MIX_RTK) /* #if defined(MIX_OS) */

    rtk_thread_sleep(rtk_msec_to_ticks(delay_ms));

#elif defined(MIX_K_KIT) /* #elif defined(MIX_RTK) */

    k_work_sleep(delay_ms);

#else /* #elif defined(MIX_K_KIT)  */

#define CPUCLK_PER_LOOP 12
    size_t cpu_clk = drv_clk_get_cpu_clk();
    size_t clks_pre_ms = cpu_clk / (CPUCLK_PER_LOOP * 1000);
    size_t max_ms = ~0 / clks_pre_ms;
    volatile size_t clks = clks_pre_ms * (delay_ms < max_ms ? delay_ms : max_ms);
    for (size_t i = 0; i < clks; i++)
    {
    }
#undef CPUCLK_PER_LOOP

#endif /* #if defined(MIX_OS) */
}
